package progress.exa28_3.part2;


import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DeadLockStudy {

    private static Buffer buffer = new Buffer();

    public static void main(String[] args) {
        //创建一个并行线程池
        ExecutorService executor= Executors.newFixedThreadPool(10);
        executor.execute(new ProducerTask());
        executor.execute(new ConsumerTask());
        executor.shutdown();
    }

    private static class ProducerTask implements Runnable{
        public void run(){
            try{
                int i=1;
                while(true){
                    System.out.println("Producer writes： "+i);
                    buffer.write(i++);

                    Thread.sleep((int)(Math.random()*1000));//线程休眠
                }
            }catch (InterruptedException ex)
            {
                ex.printStackTrace();
            }

        }
    }

    private static class ConsumerTask implements Runnable{
        public void run() {
            try {
                while (true) {
                    System.out.println("\t\t\tConsumer reads"+buffer.read());
                    Thread.sleep((int)(Math.random()*1000));//线程休眠

                }
            }catch (InterruptedException ex)
            {
                ex.printStackTrace();
            }

        }
    }

    private static class Buffer{

        private static final int CAPACITY=10;//缓冲区大小为1

        private LinkedList<Integer> queue=new LinkedList<>();

        //创建互斥锁
        private static Lock lock = new ReentrantLock();

        //创建条件锁
        private static Condition notEmpty = lock.newCondition();
        private static Condition notFull = lock.newCondition();

        public void write(int value) {
            lock.lock();//上锁
            try{
                while(queue.size()==CAPACITY){
                    System.out.println("缓冲区满了，等待读取");
                    //释放锁，线程进入等待状态
                    notFull.await();
                }
                queue.offer(value);//添加value到queue
                notEmpty.signal();//唤醒read

                //在这里添加循环，让线程一直不释放锁
                while (true){
                }

            }catch(InterruptedException ex) {
                ex.printStackTrace();
            } finally{
                lock.unlock();//解锁
            }
        }

        public int read(){
            int value=0;
            lock.lock();//上锁
            try{
                while(queue.isEmpty()){
                    System.out.println("\t\t\t缓冲区空了，等待写入");
                    //释放锁
                    notEmpty.await();
                }
                value=queue.remove();//弹出元素
                notFull.signal();//唤醒write
            }catch(InterruptedException ex){
                ex.printStackTrace();
            } finally {
                lock.unlock();//解锁
                return value;
            }
        }

    }
}
